﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace MyConsoleApp.Code
{
    /// <summary>
    /// INIFile 处理类
    /// </summary>
    public class INIFile
    {
        #region 变量和属性

        private const string iniFileName = "EMRConfig.xml";
        private static object _lock = new object();
        private static INIFile _Instance;
        private string _path;

        /// <summary>
        /// 获取客户端配置文件
        /// </summary>
        public static INIFile Instance
        {
            get
            {
                if (_Instance == null)
                {
                    lock (_lock)
                    {
                        if (_Instance == null)
                        {
                            string iniFileDir = System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                            iniFileDir = Path.Combine(iniFileDir, "MS_EMR");
                            if (!Directory.Exists(iniFileDir))
                                Directory.CreateDirectory(iniFileDir);
                            string iniFilePath = Path.Combine(iniFileDir, iniFileName);
                            _Instance = new INIFile(iniFilePath);
                        }
                    }
                }
                return _Instance;
            }
        }

        /// <summary>
        /// 查找模板时，用户输入查找字符串。
        /// </summary>
        public string LastUserSearchTemplateKey
        {
            get
            {
                return this.IniReadValue("LastUserSearchTemplateKey", "LastUserSearchTemplateKey");
            }
            set
            {
                this.IniWriteValue("LastUserSearchTemplateKey", "LastUserSearchTemplateKey", value);
            }
        }

        /// <summary>
        /// 获取或设置上次登录用户工号
        /// </summary>
        public string LastUserCode
        {
            get
            {
                return this.IniReadValue("LastUserCode", "LastUserCode");
            }
            set
            {
                this.IniWriteValue("LastUserCode", "LastUserCode", value);
            }
        }

        /// <summary>
        /// 获取或设置上次版本号
        /// </summary>
        public string LastAppVersion
        {
            get
            {
                return this.IniReadValue("LastAppVersion", "LastAppVersion");
            }
            set
            {
                this.IniWriteValue("LastAppVersion", "LastAppVersion", value);
            }
        }
        
        #endregion

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="iniPath">文件路径</param>
        public INIFile(string iniPath)
        {
            _path = iniPath;
        }

        #region 导入COM接口

        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath);

        #endregion

        #region  写INI

        /// <summary>
        /// 写INI文件
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void IniWriteValue(string section, string key, string value)
        {
            WritePrivateProfileString(section, key, value, this._path);
        }
        #endregion

        #region 删除ini配置

        /// <summary>
        /// 删除ini文件下所有段落
        /// </summary>
        private void ClearAllSection()
        {
            IniWriteValue(null, null, null);
        }
        /// <summary>
        /// 删除ini文件下personal段落下的所有键
        /// </summary>
        /// <param name="section"></param>
        private void ClearSection(string section)
        {
            IniWriteValue(section, null, null);
        }
        #endregion

        #region 读取INI

        /// <summary>
        /// 读取INI文件,返回字符串
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string IniReadValue(string section, string key)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(section, key, "", temp, 255, this._path);
            return temp.ToString();
        }

        /// <summary>
        /// 读取INI文件，返回数值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private int IniReadValueInt(string section, string key, int def)
        {
            string val = IniReadValue(section, key);
            int re = def;
            if (val.Trim() == "" || !int.TryParse(val, out re))
                re = def;
            return re;
        }

        /// <summary>
        /// 读取INI文件，返回时间
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private DateTime IniReadValueDate(string section, string key, DateTime def)
        {
            string val = IniReadValue(section, key);
            DateTime re = def;
            if (val.Trim() == "" || !DateTime.TryParse(val, out re))
                re = def;
            return re;
        }

        /// <summary>
        /// 读取INI文件，返回二进制数组
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private byte[] IniReadValues(string section, string key)
        {
            byte[] temp = new byte[255];
            int i = GetPrivateProfileString(section, key, "", temp, 255, this._path);
            return temp;
        }

        /// <summary>
        /// 读取ini文件的所有段落名
        /// </summary>    
        private string[] IniReadValues()
        {
            byte[] allSection = IniReadValues(null, null);
            return ByteToString(allSection);

        }

        /// <summary>
        /// 转换byte[]类型为string[]数组类型 
        /// </summary>
        /// <param name="sectionByte"></param>
        /// <returns></returns>
        private string[] ByteToString(byte[] sectionByte)
        {
            ASCIIEncoding ascii = new ASCIIEncoding();
            //编码所有key的string类型
            string sections = ascii.GetString(sectionByte);
            //获取key的数组
            string[] sectionList = sections.Split(new char[1] { '\0' });
            return sectionList;
        }

        /// <summary>
        /// 读取ini文件的某段落下所有键名
        /// </summary>    
        private string[] IniReadValues(string section)
        {
            byte[] sectionByte = IniReadValues(section, null);
            return ByteToString(sectionByte);
        }

        #endregion

    }
}